package cn.net.shuxing.yifu.common.service;

import cn.net.shuxing.yifu.common.bean.*;
import cn.net.shuxing.yifu.common.constant.*;
import cn.net.shuxing.yifu.common.dto.BaseDto;
import cn.net.shuxing.yifu.common.dto.DealRecordDto;
import cn.net.shuxing.yifu.common.mapper.HangSaleMapper;
import cn.net.shuxing.yifu.common.util.*;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import javafx.beans.binding.Bindings;
import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.net.shuxing.yifu.common.util.StringUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.ScanResult;
import tk.mybatis.mapper.entity.Example;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;

@Service
public class HangSaleService extends HistoryService<HangSale, HangSaleMapper> {
    @Autowired
    private UserRoleService userRoleService;

    @Autowired
    private UserDealHistoryService userDealHistoryService;

    @Autowired
    private DealHistoryService dealHistoryService;

    @Autowired
    private FeeService feeService;

    @Autowired
    private JedisUtil jedisUtil;

    @Autowired
    private UserInfoBindService userInfoBindService;

    @Autowired
    private UserRealInfoService userRealInfoService;

    @Autowired
    private UserCapitalService userCapitalService;

    @Autowired
    private UserService userService;

    @Autowired
    private DealParamService dealParamService;

    @Autowired
    private ShortService shortService;

    @Autowired
    private CoinTypeService coinTypeService;

    @Override
    public HangSale getByPrimaryKey(Object key) {
        //Jedis //jedis = jedisUtil.getJedis();
        return super.getByPrimaryKey(key);
    }

    public List<HangSale> getTotalByUserId(Integer userId, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        CommonExample example = new CommonExample(HangSale.class);
        example.equals("userId", userId);
        List<HangSale> hangSaleList = getsByExample(example);
        return hangSaleList;
    }

    public List<HangSale> getTotalByUserId(Integer userId) {
        CommonExample example = new CommonExample(HangSale.class);
        example.equals("userId", userId);
        List<HangSale> hangSaleList = getsByExample(example);
        return hangSaleList;
    }

    public List<HangSale> getTotalByUserIdWithoutComplete(Integer userId, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        CommonExample example = new CommonExample(HangSale.class);
        example.equals("userId", userId);
        List<HangSale> hangSaleList = getsByExampleWithoutComplete(example);
        return hangSaleList;
    }

    public List<HangSale> getTodayByUserId(int userId) {
        List<HangSale> hangSaleList = getByToday();
        hangSaleList.stream().forEach(
                (x) -> {
                    if (!x.getUserId().equals(userId))
                        hangSaleList.remove(x);
                });
        return hangSaleList;
    }

    public BaseDto searchByRealName(String realName) {
        BaseDto baseDto = new BaseDto();
        List<UserRealInfo> userRealInfoList = userRealInfoService.getsByRealName(realName);
        List<HangSale> hangSaleList = new ArrayList<>();
        for (UserRealInfo userRealInfo : userRealInfoList) {
            hangSaleList.addAll(getTotalByUserId(userRealInfo.getId()));
        }
        baseDto.setData(hangSaleList);
        return baseDto;
    }

    public BaseDto searchByWantAliveCoinCount(BigDecimal low, BigDecimal high) {
        CommonExample example = new CommonExample(HangSale.class);
        example.between("wantAliveCoinCount", low, high);
        List<HangSale> hangSaleList = mapper.selectByExample(example);
        completeAll(hangSaleList);
        BaseDto baseDto = new BaseDto();
        baseDto.setData(hangSaleList);
        return baseDto;
    }

    public List<HangSale> searchByPublishTime(LocalDateTime low, LocalDateTime high) {
        TimeExample example = new TimeExample(HangSale.class);
        example.between("createTime", low, high);
        List<HangSale> hangSaleList = mapper.selectByExample(example);
        completeAll(hangSaleList);
        return hangSaleList;
    }


    public void setInRedis(HangSale hangSale) {
        //Jedis //jedis = jedisUtil.getJedis();
        HangSale byPrimaryKey = getByPrimaryKey(hangSale.getId());
        if (byPrimaryKey != null)
            jedisUtil.srem(RedisKeyCreator.hangBuySet(), JSON.toJSONString(hangSale));
        jedisUtil.sadd(RedisKeyCreator.hangSaleSet(), RedisKeyCreator.hangSaleObj(hangSale.getId()));
        //jedisUtil.close();
    }

    @Override
    public int update(HangSale bean) {
        if (super.update(bean) < 1) {
            return -1;
        } else {
            setInRedis(bean);
            return 1;
        }
    }

    @Override
    public boolean delete(Object primaryKey) {
        //Jedis //jedis = jedisUtil.getJedis();
        jedisUtil.del(RedisKeyCreator.hangSaleObj((Integer) primaryKey));
        jedisUtil.srem(RedisKeyCreator.hangSaleSet(), RedisKeyCreator.hangSaleObj((Integer) primaryKey));
        //jedisUtil.close();
        HangSale hangSale = getByPrimaryKey(primaryKey);
        hangSale.setSurplusCoinCount(new BigDecimal(0));
        super.delete(primaryKey);
        return true;
    }

    public void reduceSurplusCoinCount(Integer hangSaleId, BigDecimal aliveCoinCount) {
        HangSale hangSale = getByPrimaryKey(hangSaleId);
        BigDecimal surplusCoinCount = hangSale.getSurplusCoinCount();
        surplusCoinCount = surplusCoinCount.subtract(aliveCoinCount);
        hangSale.setSurplusCoinCount(surplusCoinCount);
        update(hangSale);
    }

    public BaseDto publishHangSale(Integer userId, BigDecimal aliveCoinCount, BigDecimal singlePrice, Integer coinTypeId, Integer hangTypeId) {
        /**
         * 逻辑梳理:
         *  0. 判断当前用户是否正常,如果不是,报错
         *  1. 判断当前是否可以发布挂卖单,如果不可以,报错
         *  2. 判断挂卖方式,如果为回收挂卖,则将单价设置为开盘价
         *  3. 如果是限价挂卖,则获取限价挂卖系数, 然后判断挂卖单价是否符合规范,不符合就报错
         *  4. 查看当前挂卖量是否需要使用坐空权限,如果不要,继续
         *  5. 如果需要使用坐空,查看该用户当前剩余坐空次数,如果没有了,报错
         *  6. 如果坐空次数大于0, 将坐空次数减一并放入数据库中
         *  7. 如果一切正常,扣除活币,发布挂卖单
         */
        BaseDto baseDto = new BaseDto();
        try {
            String orderNo = userDealHistoryService.createOrderNo(8);
            /** 0. 判断当前用户是否正常,如果不是,报错 **/
            User user = userService.getByPrimaryKey(userId);
            Integer state = userRoleService.getUserStateByUserIdAndUserType(userId, UserType.MEMBER);
            if (state != UserState.OK) {
                baseDto.setCode(CodeConst.ERROR);
                baseDto.setMsg("当前状态无法发布挂卖单");
                return baseDto;
            }
            if (user.getType() == UserType.NONE)
                return BaseDto.error("请先激活账号");
            if (user.getType() != UserType.MEMBER)
                return BaseDto.error("当前身份无法发布挂卖单,请切换至会员身份");

            /** 1. 判断当前是否可以发布挂卖单,如果不可以,报错 **/
            //Jedis //jedis = jedisUtil.getJedis();
            String able = jedisUtil.get(RedisKeyCreator.ablePublishHangSale(userId));
            //jedisUtil.close();
            if (StringUtils.hasText(able)) {
                baseDto.setCode(CodeConst.ERROR);
                baseDto.setMsg("当前状态无法发布挂卖单");
                return baseDto;
            }

            /** 开盘价 **/
            BigDecimal openPrice = new BigDecimal(jedisUtil.get(RedisKeyCreator.openPrice(coinTypeId)));

            /**
             * 2. 查看当前挂卖量是否需要使用坐空权限,如果不要,继续
             * 3. 如果需要使用坐空,查看该用户当前剩余坐空次数,如果没有了,报错
             * 4. 如果坐空次数大于0, 将坐空次数减一并放入数据库中
             */
            /** 当前卖方钱包活币余额 **/
            BigDecimal saleUserAliveCoinBalance = userCapitalService.getByUserIdAndCoinTypeIdAndUserType(userId, coinTypeId, UserType.MEMBER).getAliveCoinCount();
            /** 挂卖量 必须不高于当前卖方钱包余额  **/
            /** 挂卖量 必须 小于 余额, 否则报错**/
            if (aliveCoinCount.compareTo(saleUserAliveCoinBalance) > 0) {
                baseDto.setCode(CodeConst.ERROR);
                baseDto.setMsg(" 挂卖量 必须不高于" + saleUserAliveCoinBalance);
                return baseDto;
            }
            /** 获取交易钱包最小活币量 **/
            String dealWalletMinCountStr = dealParamService.getValue(userId, coinTypeId, UserParamConst.MEMBER_KEEP_ALIVE_COIN_MIN_COUNT);
            BigDecimal dealWalletMinCount = new BigDecimal(dealWalletMinCountStr);

            /** 如果 卖方钱包余额 - 挂卖量 <  交易钱包最小活币量, 就查看坐空权限**/
            if ((saleUserAliveCoinBalance.subtract(aliveCoinCount)).compareTo(dealWalletMinCount) < 0) {
                Integer userShortCount = shortService.getUserShortCount(userId, coinTypeId);
                if (userShortCount == 0) {
                    baseDto.setCode(CodeConst.ERROR);
                    baseDto.setMsg("挂卖数量必须不高于" + (saleUserAliveCoinBalance.subtract(dealWalletMinCount)).toString());
                    return baseDto;
                } else if (userShortCount > 0) {
                    /** 使用坐空 **/
                    Integer userShortDeadline = shortService.getUserShortDeadline(userId, coinTypeId);
                    if (!shortService.insertShort(userId, coinTypeId, userShortCount - 1, userShortDeadline)) {
                        shortService.updateShort(userId, coinTypeId, userShortCount - 1, userShortDeadline);
                        jedisUtil.set(RedisKeyCreator.shortStartTime(userId), LocalDateTime.now().toString());
                    }
                }
            }

            /** 回收挂卖 **/
            if (hangTypeId == HangTypeConst.BUY_BACK_SALE) {
                if (singlePrice.compareTo(openPrice) > 0) {
                    return BaseDto.error("回收挂卖的价格不能高于开盘价");
                } else {
                    HangSale hangSale = new HangSale();
                    hangSale.setUserId(userId);
                    hangSale.setAliveCoinCount(aliveCoinCount);
                    hangSale.setCoinTypeId(coinTypeId);
                    hangSale.setSinglePrice(singlePrice);
                    hangSale.setHangTypeId(hangTypeId);
                    hangSale.setAliveCoinCount(aliveCoinCount);
                    hangSale.setState(DealState.DEALING);
                    hangSale.setDealCount(new BigDecimal(0));
                    hangSale.setSurplusCoinCount(aliveCoinCount);
                    hangSale.setOrderKey(orderNo);
                    insert(hangSale);
                    hangSale = getByPrimaryKey(hangSale.getId());
//                    setInRedis(hangSale);
                    jedisUtil.set(RedisKeyCreator.ablePublishHangSale(userId), "0");
//                    dealHistoryService.systemBuyBack(hangSale.getId());
                    BaseDto.ok("已完成请刷新");
                }
            } else if (hangTypeId == HangTypeConst.LIMIT_PRICE_BUY) {
                /** 5. 如果是限价挂卖,则获取限价挂卖系数, 然后判断挂卖单价是否符合规范,不符合就报错 **/

                /** 限价挂卖系数 **/
                BigDecimal limitPriceSale = new BigDecimal(jedisUtil.get(RedisKeyCreator.limitPriceSale()));
                /** 如果 单价 小于 今日开盘价 * (1 + 限价挂卖系数) 就报错 **/
                BigDecimal min = openPrice.multiply(new BigDecimal(1).add(limitPriceSale));
                if (singlePrice.compareTo(min) < 0) {
                    baseDto.setCode(CodeConst.ERROR);
                    baseDto.setMsg("限价挂卖方式单价必须不低于" + min);
                    return baseDto;
                } else {
                    HangSale hangSale = new HangSale();
                    hangSale.setUserId(userId);
                    hangSale.setAliveCoinCount(aliveCoinCount);
                    hangSale.setCoinTypeId(coinTypeId);
                    hangSale.setSinglePrice(singlePrice);
                    hangSale.setHangTypeId(hangTypeId);
                    hangSale.setAliveCoinCount(aliveCoinCount);
                    hangSale.setState(DealState.DEALING);
                    hangSale.setDealCount(new BigDecimal(0));
                    hangSale.setSurplusCoinCount(aliveCoinCount);
                    hangSale.setOrderKey(orderNo);
                    insert(hangSale);
                    hangSale = super.getByPrimaryKey(hangSale.getId());
//                    setInRedis(hangSale);
                    baseDto.setData(hangSale);
                    jedisUtil.set(RedisKeyCreator.ablePublishHangSale(userId), "0");
                    //jedisUtil.close();

                    /** 6. 如果一切正常,扣除活币,发布挂卖单 **/
                    /** 插入活币变动记录 **/
                    userDealHistoryService.insert(userId, coinTypeId, DealType.HANG_SALE, DealScene.NONE, aliveCoinCount, hangSale.getSinglePrice(), UserType.MEMBER, orderNo);
                    userCapitalService.reduceAliveCoin(userId, coinTypeId, aliveCoinCount, UserType.MEMBER);
                    /** 插入手续费记录 **/
                    Fee fee = feeService.getFee(userId, coinTypeId, DealScene.HANG_SALE);
                    BigDecimal feeRatio = fee.getFeeRatio();
                    BigDecimal baseDealCount = fee.getBaseDealCount();
                    BigDecimal feeCount = (aliveCoinCount.subtract(baseDealCount)).multiply(feeRatio);
                    userDealHistoryService.insert(userId, coinTypeId, DealType.FEE, DealScene.HANG_SALE, feeCount, hangSale.getSinglePrice(), UserType.MEMBER, orderNo);

                    /** 扣除手续费 **/
                    feeService.reduceFee(userId, coinTypeId, DealScene.HANG_SALE, aliveCoinCount, singlePrice, UserType.MEMBER);
                }
            }

        } catch (Exception e) {
            baseDto.setCode(CodeConst.ERROR);
            baseDto.setMsg(MsgConst.REDIS_ERROR);
            return baseDto;
        }
        return baseDto;
    }

    public BaseDto searchByPhoneNum(String phoneNum) {
        BaseDto baseDto = new BaseDto();
        try {
            UserInfoBind userInfoBind = userInfoBindService.getByPhoneNum(phoneNum);
            List<HangSale> hangSaleList = getTotalByUserId(userInfoBind.getId());
            baseDto.setData(hangSaleList);
        } catch (Exception e) {
            baseDto.setCode(CodeConst.ERROR);
            baseDto.setMsg(MsgConst.REDIS_ERROR);
        }
        return baseDto;
    }

    public List<HangSale> searchHangSale(String phoneNum, String realName, BigDecimal lowAliveCount, BigDecimal highAliveCount, BigDecimal lowDealtCount, BigDecimal highDealtCount, LocalDate lowDate, LocalDate highDate) {
        List<Integer> userIdList = new ArrayList<>();
        List<HangSale> resultList = new ArrayList<>();
        if (StringUtils.hasText(phoneNum)) {
            userIdList.add(userInfoBindService.getByPhoneNum(phoneNum).getId());
        } else {
            List<UserRealInfo> userRealInfoList = userRealInfoService.getsByRealName(realName);
            userRealInfoList.forEach((x) -> {
                userIdList.add(x.getId());
            });
        }
        if (userIdList == null || userIdList.isEmpty()) {
            List<User> all = userService.getAll();
            for (User user : all) {
                Integer id = user.getId();
                userIdList.add(id);
            }
        }

        for (Integer userId : userIdList) {
            CommonExample example = new CommonExample(HangSale.class);
            Example.Criteria criteria = example.getCriteria();
            example.equals("userId", userId);
            if (lowAliveCount != null) {
                criteria.andGreaterThanOrEqualTo("aliveCoinCount", lowAliveCount);
            }
            if (highAliveCount != null) {
                criteria.andLessThanOrEqualTo("aliveCoinCount", highAliveCount);
            }
            if (lowDate != null) {
                LocalDateTime lowDateTime = LocalDateTimeUtil.createLocalDateTime(lowDate, LocalTimeUtil.createLocalTimeInZero());
                criteria.andGreaterThanOrEqualTo("createTime", lowDateTime);
            }
            if (highDate != null) {
                LocalDateTime highDateTime = LocalDateTimeUtil.createLocalDateTime(highDate.plusDays(1), LocalTimeUtil.createLocalTimeInZero());
                criteria.andLessThan("createTime", highDateTime);
            }
            List<HangSale> hangSaleList = mapper.selectByExample(example);
            completeAll(hangSaleList);


            if (lowDealtCount != null) {
//                for (HangSale hangSale : saleArrayList) {
//                    BigDecimal dealCount = hangSale.getDealCount();
//                    int i = dealCount.compareTo(lowDealtCount);
//                    if (i<0){
//                        saleArrayList.remove(hangSale);
//                    }
////                    if (saleArrayList.size()==0){
////                        break;
////                    }
//                }
                for (int i = 0; i < hangSaleList.size(); i++) {
                    HangSale hangSale = hangSaleList.get(i);
                    BigDecimal dealCount = hangSale.getDealCount();
                    int s = dealCount.compareTo(lowDealtCount);
                    if (s < 0) {
                        hangSaleList.remove(i);
                    }
                }

            }
            if (highDealtCount != null) {
                for (int i = 0; i < hangSaleList.size(); i++) {
                    HangSale hangSale = hangSaleList.get(i);
                    BigDecimal dealCount = hangSale.getDealCount();
                    int s = dealCount.compareTo(highDealtCount);
                    if (s > 0) {
                        hangSaleList.remove(i);
                    }
                }
            }

            resultList.addAll(hangSaleList);
        }
        return resultList;
    }

    public BaseDto cancel(Integer hangSaleId) {
        BaseDto baseDto = new BaseDto();
        HangSale hangSale = getByPrimaryKey(hangSaleId);
        if (hangSale.getState() != DealState.CANCEL && hangSale.getState() != DealState.COMPLETED) {
            userCapitalService.addAliveCoin(hangSale.getUserId(), hangSale.getCoinTypeId(), hangSale.getSurplusCoinCount(), UserType.MEMBER);
            userDealHistoryService.insert(hangSale.getUserId(), hangSale.getCoinTypeId(), DealType.HANG_SALE_CANSEL, DealScene.NONE, hangSale.getSurplusCoinCount(), hangSale.getSinglePrice(), UserType.MEMBER, hangSale.getOrderKey());
            hangSale.setState(DealState.CANCEL);
            update(hangSale);
            //Jedis //jedis = jedisUtil.getJedis();
            jedisUtil.del(RedisKeyCreator.hangSaleObj(hangSale.getId()));
            jedisUtil.srem(RedisKeyCreator.hangSaleSet(), RedisKeyCreator.hangSaleObj(hangSale.getId()));
            // TODO: 2019/4/16 上线的时候要把这个打开
//            LocalDate createDate = LocalDateTimeUtil.getLocalDate(hangSale.getCreateTime());
//            if (!LocalDate.now().equals(createDate))
//                jedisUtil.del(RedisKeyCreator.ablePublishHangSale(hangSale.getUserId()));
//            //jedisUtil.close();
            // TODO: 2019/4/16 上线的时候要把这个注释掉
            LocalDateTime localDateTime = hangSale.getCreateTime().plusMinutes(5);
            if (LocalDateTime.now().compareTo(localDateTime) >= 0) {
                jedisUtil.del(RedisKeyCreator.ablePublishHangSale(hangSale.getUserId()));
            }
            //jedisUtil.close();
        } else {
            baseDto.setCode(CodeConst.ERROR);
            baseDto.setMsg("此单已被撤销或已完成");
        }
        return baseDto;
    }

    public void setHangSaleCompleted(HangSale hangSale) {
        hangSale.setState(DealState.COMPLETED);
        hangSale.setDealCount(hangSale.getAliveCoinCount());
        hangSale.setSurplusCoinCount(new BigDecimal(0));
        update(hangSale);
        //Jedis //jedis = jedisUtil.getJedis();
        jedisUtil.del(RedisKeyCreator.hangSaleObj(hangSale.getId()));
        jedisUtil.srem(RedisKeyCreator.hangSaleSet(), RedisKeyCreator.hangSaleObj(hangSale.getId()));
        LocalDate createDate = LocalDateTimeUtil.getLocalDate(hangSale.getCreateTime());
        // TODO: 2019/4/16 上线的时候要把这个打开
//        if (!LocalDate.now().equals(createDate))
//            jedisUtil.del(RedisKeyCreator.ablePublishHangSale(hangSale.getUserId()));
//        //jedisUtil.close();
        // TODO: 2019/4/16 上线的时候要把这个注释掉
        LocalDateTime localDateTime = hangSale.getCreateTime().plusMinutes(5);
        if (LocalDateTime.now().compareTo(localDateTime) >= 0) {
            jedisUtil.del(RedisKeyCreator.ablePublishHangSale(hangSale.getUserId()));
        }
        //jedisUtil.close();
    }

    public HangSale getDealingByUserId(Integer userId) {
        HangSale hangSale = new HangSale();
        hangSale.clearCreateTimeAndUpdateTime();
        hangSale.setState(DealState.DEALING);
        hangSale.setUserId(userId);
        HangSale hangSale1 = get(hangSale);
        if (hangSale1 != null) {
            hangSale1.setSimpleName(coinTypeService.getByPrimaryKey(hangSale1.getCoinTypeId()).getSimpleName());
        }
        return hangSale1;
    }

    public List<HangSale> getHangSaleRank(Integer coinTypeId, int i) {
//        select * from hang_buy where coin_type_id = ? and state = DealState.DEALING ORDER BY single_price asc LIMIT 1
        PageHelper.startPage(1, i);
        CommonExample example = new CommonExample(HangSale.class);
        example.equals("coinTypeId", coinTypeId);
        example.equals("state", DealState.DEALING);
        example.setOrderByClause("single_price asc");
//        List<HangSale> hangSaleList = mapper.selectByExampleAndRowBounds(example, new RowBounds(0, i));
        List<HangSale> hangSaleList = getsByExample(example);
        completeAll(hangSaleList);
        return hangSaleList;
    }

    public Integer getTotalCount() {
        return getAll().size();
    }

    public Integer getTodayCount() {
        return getByToday().size();
    }

    public List<HangSale> getCompletedHangSale(Integer userId, Integer coinTypeId, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        CommonExample example = new CommonExample(HangSale.class);
        example.equals("userId", userId)
                .equals("coinTypeId", coinTypeId)
                .equals("state", DealState.COMPLETED);

        List<HangSale> hangSales = getsByExample(example);
        for (HangSale hangSale : hangSales) {
            hangSale.setSimpleName(coinTypeService.getByPrimaryKey(coinTypeId).getSimpleName());
        }
        return hangSales;
    }

    //select * from hang_sale where userId = userId and coinTypeId = coinTypeId and state = DealState.CANCEl
    public List<HangSale> getCancelHangSale(Integer userId, Integer coinTypeId, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        CommonExample example = new CommonExample(HangSale.class);
        example.equals("userId", userId)
                .equals("coinTypeId", coinTypeId)
                .equals("state", DealState.CANCEL);
        example.setOrderByClause("id DESC");
        List<HangSale> hangSales = getsByExample(example);
        for (HangSale hangSale : hangSales) {
            hangSale.setSimpleName(coinTypeService.getByPrimaryKey(coinTypeId).getSimpleName());
        }
        return hangSales;
    }

    public List<HangSale> getTotalByUserIdAndCoinType(Integer userId, Integer coinTypeId, Integer pageNum, Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        CommonExample example = new CommonExample(HangSale.class);
        example.equals("userId", userId)
                .equals("coinTypeId", coinTypeId);
        example.setOrderByClause("id DESC");
        List<HangSale> hangSales = getsByExample(example);
        for (HangSale hangSale : hangSales) {
            hangSale.setSimpleName(coinTypeService.getByPrimaryKey(coinTypeId).getSimpleName());
        }
        return hangSales;
    }

    public List<HangSale> getTotalByUserIdAndCoinType(Integer userId, Integer coinTypeId) {
        CommonExample example = new CommonExample(HangSale.class);
        example.equals("userId", userId)
                .equals("coinTypeId", coinTypeId);
        example.setOrderByClause("id DESC");
        return getsByExample(example);
    }

    public List<HangSale> getTodayByUserIdAndCoinTypeId(Integer userId, Integer coinTypeId) {
        CommonExample example = new CommonExample(HangSale.class);
        example.equals("userId", userId);
        example.equals("coinTypeId", coinTypeId);
        Example.Criteria criteria = example.getCriteria();
        criteria.andGreaterThanOrEqualTo("createTime", LocalDateTimeUtil.getToday());
        return getsByExample(example);
    }

    @Override
    protected void complete(HangSale bean) {
        Integer coinTypeId = bean.getCoinTypeId();
        String simpleName = coinTypeService.getByPrimaryKeyWithoutComplete(coinTypeId).getSimpleName();
        bean.setSimpleName(simpleName);
//        BigDecimal subtract = bean.getAliveCoinCount().subtract(bean.getSurplusCoinCount());
        BigDecimal aliveCoinCount = bean.getAliveCoinCount();
        BigDecimal surplusCoinCount = bean.getSurplusCoinCount();
        BigDecimal subtract = aliveCoinCount.subtract(surplusCoinCount);

//        BigDecimal mData = subtract.setScale(8, BigDecimal.ROUND_HALF_UP);
        bean.setDealCount(subtract);

    }

    public List<HangSale> getByState(int state) {
        CommonExample example = new CommonExample(HangSale.class);
        example.equals("state", state);
        List<HangSale> hangSales = getsByExample(example);
        return hangSales;
    }

    public List<HangSale> getByHangTypeAndState(int hangType, int state) {
        CommonExample example = new CommonExample(HangSale.class);
        example.equals("hangTypeId", hangType);
        example.equals("state", state);
        return getsByExampleWithoutComplete(example);
    }

    public List<DealRecordDto> getByCoinTypeIdAndState(Integer coinTypeId) {
        CommonExample example = new CommonExample(HangSale.class);
        example.equals("coinTypeId", coinTypeId);
        example.equals("state", DealState.DEALING);
        List<HangSale> hangBuys = getsByExampleWithoutComplete(example);
        ArrayList<DealRecordDto> listDto = new ArrayList<>();
        if (hangBuys != null && !hangBuys.isEmpty()) {
            for (HangSale hangBuy : hangBuys) {
                DealRecordDto dealRecordDto = new DealRecordDto();
                dealRecordDto.setDealType(DealType.HANG_BUY);
                dealRecordDto.setDealAliveCoinCount(hangBuy.getAliveCoinCount());
                dealRecordDto.setSurplusCount(hangBuy.getSurplusCoinCount());
                dealRecordDto.setCreateTime(hangBuy.getCreateTime());
                dealRecordDto.setDealPrice(hangBuy.getSinglePrice());
                listDto.add(dealRecordDto);
            }
        }
        return listDto;
    }
}
